﻿using ASoft.Msg;
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace ASoft.Service
{
    public class PhoneMsgService
    {

        SerialPort serialPort = new SerialPort();

        public bool Enable
        {
            get { return RC.Current.RootData.MsgEnable && !string.IsNullOrWhiteSpace(RC.Current.RootData.PhonePortName); }
        }

        public void OpenPort()
        {
            if (!Enable)
            {
                return;
            }

            if (serialPort.IsOpen)
            {
                return;
            }
            serialPort.PortName = RC.Current.RootData.PhonePortName;
            serialPort.BaudRate = 9600;
            serialPort.Parity = Parity.None;
            serialPort.DataBits = 8;
            serialPort.StopBits = StopBits.One;

            serialPort.Open();

            serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort_DataReceived);
            serialPort.ErrorReceived += new SerialErrorReceivedEventHandler(serialPort_ErrorReceived);

            RC.Current.Loger.Trace(string.Format("Phone SerialPort Open:{0}", Format(serialPort)));

        }

        static object lockKey = new object();
        /// <summary>
        /// 数据接收处理
        /// </summary>
        void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            byte[] data = new byte[serialPort.BytesToRead];
            serialPort.Read(data, 0, data.Length);
            if (phoneMsg == null)
            {
                phoneMsg = new PhoneMsg();
            }

            phoneMsg.AppendBytes(data);

            if (phoneMsg.IsOk)
            {
                var msg = phoneMsg;
                RC.Current.Loger.Trace(msg.ToString());
                lock (lockKey)
                {
                    phoneMsg = new PhoneMsg();
                }
                OnMsgOK(this, new PhoneMsgEventArgs(msg));
            }
        }

        public event PhoneMsgEventHandler MsgOK;

        public void OnMsgOK(object sender, PhoneMsgEventArgs e)
        {
            if (MsgOK != null)
            {
                MsgOK(sender, e);
            }
        }

        PhoneMsg phoneMsg = null;

        /// <summary>
        /// 错误处理函数
        /// </summary>
        void serialPort_ErrorReceived(object sender, SerialErrorReceivedEventArgs e)
        {
            //throw new ErrorReceivedException(e);
            RC.Current.Loger.Trace(e.ToString());
        }

        public void ClosePort()
        {

            if (serialPort.IsOpen)
            {
                serialPort.Close();
                RC.Current.Loger.Trace(string.Format("Phone SerialPort Close:{0}", Format(serialPort)));
            }
        }

        public string Format(SerialPort port)
        {
            return String.Format("{0} ({1},{2},{3},{4},{5})",
                port.PortName, port.BaudRate, port.DataBits, port.StopBits, port.Parity, port.Handshake);
        }


        ~PhoneMsgService()
        {
            ClosePort();
        }

        public static bool PhoneMsgCanUse(PhoneMsg phoneMsg)
        {
            if (!phoneMsg.IsOk)
            {
                return false;
            }
            if (RC.Current.RootData.Phone1Enable && RC.Current.RootData.Phone1Number == phoneMsg.PhoneNumber)
            {
                return true;
            }
            if (RC.Current.RootData.Phone2Enable && RC.Current.RootData.Phone2Number == phoneMsg.PhoneNumber)
            {
                return true;
            }
            if (RC.Current.RootData.Phone3Enable && RC.Current.RootData.Phone3Number == phoneMsg.PhoneNumber)
            {
                return true;
            }
            return false;
        }


        public static RoomSetMsg GetAndChangeRoomSet(PhoneMsg phoneMsg, out string returnMsg)
        {
            string roomName = "";
            string commandStr = "";
            var m = Regex.Match(phoneMsg.Msg, @"(\S*)温室(\S*)");
            if (m.Groups.Count == 3)
            {
                roomName = m.Groups[1].Value;
                commandStr = m.Groups[2].Value;
            }
            if (string.IsNullOrWhiteSpace(roomName))
            {
                returnMsg = "消息的温室名称为空.";
                return null;
            }

            var room = RC.Current.RootData.温室集合.FirstOrDefault(p => p.RoomName == roomName);

            if (room == null)
            {
                returnMsg = "消息的温室名称未找到.";
                return null;
            }

            var result = RC.Current.RootData.温室设置信息集合.First(p => p.Id == room.Id);

            switch (commandStr)
            {
                case "1#拉幕展开":
                    result.P1拉幕手动自动标志 = 0;
                    result.P1拉幕手动运行方向EX = 1;
                    result.P1拉幕手动运行幅度 = 100;
                    break;
                case "1#拉幕合拢":
                    result.P1拉幕手动自动标志 = 0;
                    result.P1拉幕手动运行方向EX = 0;
                    result.P1拉幕手动运行幅度 = 100;
                    break;
                case "1#拉幕自动":
                    result.P1拉幕手动自动标志 = 1;
                    break;

                case "2#拉幕展开":
                    result.P2拉幕手动自动标志 = 0;
                    result.P2拉幕手动运行方向EX = 1;
                    result.P2拉幕手动运行幅度 = 100;
                    break;
                case "2#拉幕合拢":
                    result.P2拉幕手动自动标志 = 0;
                    result.P2拉幕手动运行方向EX = 0;
                    result.P2拉幕手动运行幅度 = 100;
                    break;
                case "2#拉幕自动":
                    result.P2拉幕手动自动标志 = 1;
                    break;

                case "1#通风窗开":
                    result.P1通风窗手动自动标志 = 0;
                    result.P1通风窗手动运行方向EX = 1;
                    result.P1通风窗手动运行幅度 = 100;
                    break;
                case "1#通风窗关":
                    result.P1通风窗手动自动标志 = 0;
                    result.P1通风窗手动运行方向EX = 0;
                    result.P1通风窗手动运行幅度 = 100;
                    break;
                case "1#通风窗自动":
                    result.P1通风窗手动自动标志 = 1;
                    break;

                case "2#通风窗开":
                    result.P2通风窗手动自动标志 = 0;
                    result.P2通风窗手动运行方向EX = 1;
                    result.P2通风窗手动运行幅度 = 100;
                    break;
                case "2#通风窗关":
                    result.P2通风窗手动自动标志 = 0;
                    result.P2通风窗手动运行方向EX = 0;
                    result.P2通风窗手动运行幅度 = 100;
                    break;
                case "2#通风窗自动":
                    result.P2通风窗手动自动标志 = 1;
                    break;


                case "风机开":
                    result.风机手动自动标志 = 0;
                    result.风机手动运行方向EX = 1;
                    break;
                case "风机停":
                    result.风机手动自动标志 = 0;
                    result.风机手动运行方向EX = 0;
                    break;
                case "风机自动":
                    result.风机手动自动标志 = 1;
                    break;

                case "湿帘泵开":
                    result.湿帘泵手动自动标志 = 0;
                    result.湿帘泵手动运行方向EX = 1;
                    break;
                case "湿帘泵停":
                    result.湿帘泵手动自动标志 = 0;
                    result.湿帘泵手动运行方向EX = 0;
                    break;
                case "湿帘泵自动":
                    result.湿帘泵手动自动标志 = 1;
                    break;


                case "灌溉开":
                    result.灌溉加湿电磁阀手动自动标志 = 0;
                    result.灌溉加湿电磁阀手动运行方向EX = 1;
                    break;
                case "灌溉停":
                    result.灌溉加湿电磁阀手动自动标志 = 0;
                    result.灌溉加湿电磁阀手动运行方向EX = 0;
                    break;
                case "灌溉自动":
                    result.灌溉加湿电磁阀手动自动标志 = 1;
                    break;

                default:
                    returnMsg = string.Format("命令为实现：'{0}' ", commandStr);
                    return null;
            }
            returnMsg = "";
            return result;
        }

    }


    public class PhoneMsgEventArgs : EventArgs
    {
        public PhoneMsgEventArgs(PhoneMsg msg)
        {

            Msg = msg;
        }

        public PhoneMsg Msg { get; private set; }
    }

    public delegate void PhoneMsgEventHandler(object sender, PhoneMsgEventArgs e);
}
